package com.wenlin.myproduction.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;

import com.wenlin.myproduction.R;
import com.wenlin.myproduction.util.ScreenUtils;


public class CircleProgress extends View {
	private Paint finishedPaint;
	private Paint unfinishedPaint;
	private Paint innerCirclePaint;

	private RectF allRect = new RectF();
	private RectF progressRect = new RectF();

	private int progress = 0;
	private int max;
	private int finishedStrokeColor;
	private int unfinishedStrokeColor;
	private int startingDegree;
	private float finishedStrokeWidth;
	private float unfinishedStrokeWidth;
	private int innerBackgroundColor;


	private final float default_stroke_width;
	private final int default_finished_color = Color.rgb(66, 145, 241);
	private final int default_unfinished_color = Color.rgb(204, 204, 204);
	private final int default_text_color = Color.RED;
	private final int default_inner_background_color = Color.TRANSPARENT;
	private final int default_max = 100;
	private final int default_startingDegree = 270;


	private static final String INSTANCE_STATE = "saved_instance";
	private static final String INSTANCE_TEXT_COLOR = "text_color";
	private static final String INSTANCE_TEXT_SIZE = "text_size";
	private static final String INSTANCE_TEXT = "text";

	private static final String INSTANCE_FINISHED_STROKE_COLOR = "finished_stroke_color";
	private static final String INSTANCE_UNFINISHED_STROKE_COLOR = "unfinished_stroke_color";
	private static final String INSTANCE_MAX = "max";
	private static final String INSTANCE_PROGRESS = "progress";
	private static final String INSTANCE_SUFFIX = "suffix";
	private static final String INSTANCE_PREFIX = "prefix";
	private static final String INSTANCE_FINISHED_STROKE_WIDTH = "finished_stroke_width";
	private static final String INSTANCE_UNFINISHED_STROKE_WIDTH = "unfinished_stroke_width";
	private static final String INSTANCE_BACKGROUND_COLOR = "inner_background_color";
	private static final String INSTANCE_STARTING_DEGREE = "starting_degree";

	public CircleProgress(Context context) {
		this(context, null);
	}

	public CircleProgress(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);

		default_stroke_width = ScreenUtils.dpToPx(context,2);

		final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgress,
				defStyleAttr, 0);
		initByAttributes(attributes);
		attributes.recycle();

		initPainters();
	}

	protected void initPainters() {
		finishedPaint = new Paint();
		finishedPaint.setColor(finishedStrokeColor);
		finishedPaint.setStyle(Paint.Style.STROKE);
		finishedPaint.setAntiAlias(true);
		finishedPaint.setStrokeWidth(finishedStrokeWidth);

		unfinishedPaint = new Paint();
		unfinishedPaint.setColor(unfinishedStrokeColor);
		unfinishedPaint.setStyle(Paint.Style.STROKE);
		unfinishedPaint.setAntiAlias(true);
		unfinishedPaint.setStrokeWidth(unfinishedStrokeWidth);

		innerCirclePaint = new Paint();
		innerCirclePaint.setColor(innerBackgroundColor);
		innerCirclePaint.setAntiAlias(true);
	}

	protected void initByAttributes(TypedArray attributes) {
		finishedStrokeColor = attributes.getColor(R.styleable.CircleProgress_circle_finished_color,
				default_finished_color);
		unfinishedStrokeColor = attributes.getColor(R.styleable.CircleProgress_circle_unfinished_color,
				default_unfinished_color);

		setMax(attributes.getInt(R.styleable.CircleProgress_circle_max, default_max));
		setProgress(attributes.getInt(R.styleable.CircleProgress_circle_progress, 0));
		finishedStrokeWidth = attributes.getDimension(R.styleable.CircleProgress_circle_finished_stroke_width,
				default_stroke_width);
		unfinishedStrokeWidth = attributes.getDimension(R.styleable.CircleProgress_circle_unfinished_stroke_width,
				default_stroke_width);
		innerBackgroundColor = attributes.getColor(R.styleable.CircleProgress_circle_background_color,
				default_inner_background_color);

		startingDegree = attributes.getInt(R.styleable.CircleProgress_circle_circle_starting_degree,
				default_startingDegree);
	}

	@Override
	public void invalidate() {
		initPainters();
		super.invalidate();
	}

	public float getFinishedStrokeWidth() {
		return finishedStrokeWidth;
	}

	public void setFinishedStrokeWidth(float finishedStrokeWidth) {
		this.finishedStrokeWidth = finishedStrokeWidth;
		this.invalidate();
	}

	public float getUnfinishedStrokeWidth() {
		return unfinishedStrokeWidth;
	}

	public void setUnfinishedStrokeWidth(float unfinishedStrokeWidth) {
		this.unfinishedStrokeWidth = unfinishedStrokeWidth;
		this.invalidate();
	}

	private float getProgressAngle() {
		return getProgress() / (float) max * 360f;
	}

	public int getProgress() {
		return progress;
	}

	public void setProgress(int progress) {
		this.progress = progress;
		if (this.progress > getMax()) {
			this.progress %= getMax();
		}
		invalidate();
	}

	public int getMax() {
		return max;
	}

	public void setMax(int max) {
		if (max > 0) {
			this.max = max;
			invalidate();
		}
	}

	public int getFinishedStrokeColor() {
		return finishedStrokeColor;
	}

	public void setFinishedStrokeColor(int finishedStrokeColor) {
		this.finishedStrokeColor = finishedStrokeColor;
		finishedPaint.setColor(finishedStrokeColor);

		this.invalidate();
	}

	public int getUnfinishedStrokeColor() {
		return unfinishedStrokeColor;
	}

	public void setUnfinishedStrokeColor(int unfinishedStrokeColor) {
		this.unfinishedStrokeColor = unfinishedStrokeColor;
		unfinishedPaint.setColor(unfinishedStrokeColor);
		this.invalidate();
	}

	public int getInnerBackgroundColor() {
		return innerBackgroundColor;
	}

	public void setInnerBackgroundColor(int innerBackgroundColor) {
		this.innerBackgroundColor = innerBackgroundColor;
		this.invalidate();
	}

	public int getStartingDegree() {
		return startingDegree;
	}

	public void setStartingDegree(int startingDegree) {
		this.startingDegree = startingDegree;
		this.invalidate();
	}


	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		float delta = Math.max(finishedStrokeWidth, unfinishedStrokeWidth);
		allRect.set(delta, delta, getWidth() - delta, getHeight() - delta);
		progressRect.set(delta, delta, getWidth() - delta, getHeight() - delta);
		float innerCircleRadius = (getWidth() - Math.min(finishedStrokeWidth, unfinishedStrokeWidth)
				+ Math.abs(finishedStrokeWidth - unfinishedStrokeWidth)) / 2f;
		canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, innerCircleRadius, innerCirclePaint);
		canvas.drawArc(allRect, getStartingDegree() + getProgressAngle(), 360 - getProgressAngle(), false,
				unfinishedPaint);
		canvas.drawArc(allRect, getStartingDegree(), getProgressAngle(), false, finishedPaint);
	}

	@Override
	protected Parcelable onSaveInstanceState() {
		final Bundle bundle = new Bundle();
		bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
		bundle.putInt(INSTANCE_FINISHED_STROKE_COLOR, getFinishedStrokeColor());
		bundle.putInt(INSTANCE_UNFINISHED_STROKE_COLOR, getUnfinishedStrokeColor());
		bundle.putInt(INSTANCE_MAX, getMax());
		bundle.putInt(INSTANCE_STARTING_DEGREE, getStartingDegree());
		bundle.putInt(INSTANCE_PROGRESS, getProgress());
		bundle.putFloat(INSTANCE_FINISHED_STROKE_WIDTH, getFinishedStrokeWidth());
		bundle.putFloat(INSTANCE_UNFINISHED_STROKE_WIDTH, getUnfinishedStrokeWidth());
		bundle.putInt(INSTANCE_BACKGROUND_COLOR, getInnerBackgroundColor());
		return bundle;
	}

	@Override
	protected void onRestoreInstanceState(Parcelable state) {
		if (state instanceof Bundle) {
			final Bundle bundle = (Bundle) state;
			finishedStrokeColor = bundle.getInt(INSTANCE_FINISHED_STROKE_COLOR);
			unfinishedStrokeColor = bundle.getInt(INSTANCE_UNFINISHED_STROKE_COLOR);
			finishedStrokeWidth = bundle.getFloat(INSTANCE_FINISHED_STROKE_WIDTH);
			unfinishedStrokeWidth = bundle.getFloat(INSTANCE_UNFINISHED_STROKE_WIDTH);
			innerBackgroundColor = bundle.getInt(INSTANCE_BACKGROUND_COLOR);
			initPainters();
			setMax(bundle.getInt(INSTANCE_MAX));
			setStartingDegree(bundle.getInt(INSTANCE_STARTING_DEGREE));
			setProgress(bundle.getInt(INSTANCE_PROGRESS));
			super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
			return;
		}
		super.onRestoreInstanceState(state);
	}
}
